package com.guo.picturegallery;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;

import java.util.HashMap;
import java.util.Map;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;

/**
 * 为了点击item使相应的item居中显示，且实现RecyclerView的平缓滑动，重写LinearLayoutManager<P/>
 * @author mailanglideguozhe 20210520
 */
public class GalleryLayoutManager extends LinearLayoutManager {

    private static final String TAG = "GalleryLayoutManager";

    public GalleryLayoutManager(Context context) {
        super(context);
    }

    public GalleryLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public GalleryLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }



    //============================


    /**
     * 用于存储子视图的在RecyclerView中的位置<P/>
     * key为子视图的序号，Rect为子视图的位置<P/>
     */
    private Map<Integer , Rect> mChildPositionRects = new HashMap<>();
    /**
     * 用于记录子视图是否已经添加至RecyclerView中
     * key为子视图的序号，value为为该子视图是否在可视区域，true表示已显示，false未显示
     */
    private Map<Integer , Boolean> mChildHasAttached = new HashMap<>();

    private int mChildIntervalWidth = -20;
    int mChildWidth =0;
    int mChildHeight =0;
    float OVERLYING_RATIO = 1.2f;

    int mStartX = 0;

    /**
     * 计算显示的视图的中间视图的位置，基本思路是基于RecyclerView滑动的距离除以子视图间距
     */
    public int getCenterVisiblePosition(){
//        int position = mScrollDistanceX / mChildIntervalWidth;
//        int offset = mScrollDistanceX % mChildIntervalWidth;
//        if(offset > mChildIntervalWidth/2){
//            position++;
//        }
//        return position;

        return getFirstVisiblePosition()+3;

//        if(getChildCount() < 0){
//            return  0;
//        }
//        View item = getChildAt(getChildCount()/2);
//        return getPosition(item) ;
    }

    //计算显示的第一个视图的位置
    public int getFirstVisiblePosition(){
        if(getChildCount() < 0){
            return  0;
        }
        View item = getChildAt(0);
        return getPosition(item);
    }

//    @Override
//    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
//        if(getItemCount() == 0){
//            detachAndScrapAttachedViews(recycler);
//            return;
//        }
//        mChildHasAttached.clear();
//        mChildPositionRects.clear();
//        detachAndScrapAttachedViews(recycler);
//        //计算子视图宽度，相邻子视图间距
//        if(mChildIntervalWidth <= 0){
//            View firstItem = recycler.getViewForPosition(0);
//            measureChildWithMargins(firstItem, 0, 0);
//            mChildWidth = getDecoratedMeasuredWidth(firstItem);
//            mChildHeight = getDecoratedMeasuredHeight(firstItem);
//            mChildIntervalWidth = (int) (mChildWidth*OVERLYING_RATIO);
//        }
//        //子视图水平方向的偏移量
//        int offsetX = 0;
//        mStartX = getWidth()/2 - mChildWidth/2;
//        for(int i = 0 ; i < getItemCount() ; i++){
//            Rect rect = new Rect(offsetX + mStartX , 0 ,
//                    offsetX + mChildWidth + mStartX , mChildHeight);
//            mChildPositionRects.put(i , rect);
//            mChildHasAttached.put(i,false);
//            offsetX += mChildIntervalWidth;
//        }
//        //添加可视区域的视图
//        int visibleCount = getHorizontalSpace() / mChildIntervalWidth;
////        int visibleCount =7;
//        Rect visibleRect = getVisibleArea();
//        for(int i = 0; i < visibleCount; i++){
//            insertView(i, visibleRect, recycler, false);
//            Log.d(TAG,"the i ="+i+" visible count = "+visibleCount+",rect left = "+visibleRect.left);
//        }
//    }
//
//    private int getHorizontalSpace() {
//        return getWidth() - getPaddingLeft() - getPaddingRight();
//    }
//
//    private Rect getVisibleArea(){
//        Rect rect = new Rect(0 ,0 ,getWidth() ,getHeight());
//        return rect;
//    }
//
//
//
//
//    //横向移动的绝对距离
//    private int mScrollDistanceX = 0;
//    @Override
//    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
//        //如视图内无可显示的子视图，不累加
//        if(getChildCount() <= 0){
//            return dx;
//        }
//        int travel = dx;
//        //左边缘
//        if(mScrollDistanceX + dx < 0){
//            Log.d(TAG,"到达左边缘");
//            travel = -mScrollDistanceX;
//        }else if(mScrollDistanceX + dx > ((getItemCount() -1)*mChildIntervalWidth)){
//            //右边缘
//            Log.d(TAG,"到达右边缘");
//            travel = (getItemCount() -1)*mChildIntervalWidth - mScrollDistanceX;
//        }
//        mScrollDistanceX += travel;
//        //回收非显示区域子视图，并且在可见区域放置子视图
//        Rect visibleRect = getVisibleArea();
//        for(int i = getChildCount()-1; i >=0 ; i--){
//            View item = getChildAt(i);
//            int position = getPosition(item);
//            Rect rect = mChildPositionRects.get(position);
//            //判断子视图与可见区域无交集时，移除并回收视图
//            if(!Rect.intersects(rect,visibleRect)){
//                removeAndRecycleView(item,recycler);
//                mChildHasAttached.put(position,false);
//                Log.d(TAG,"移除视图 位置："+position);
//            }else{
//                //可视区域放置子视图
//                layoutDecoratedWithMargins(item , rect.left - mScrollDistanceX, rect.top ,
//                        rect.right - mScrollDistanceX, rect.bottom);
//                mChildHasAttached.put(position , true);
//                Log.d(TAG,"放置视图 位置："+position);
//            }
//        }
//        //RecyclerView头尾填充空白区域
//        View firstItem = getChildAt(0);
//        View lastItem = getChildAt(getChildCount() - 1);
//        if(travel >= 0 ){
//            //左滑：向底部滑动
//            int minPos = getPosition(firstItem);
//            //填充可视区域右侧的View
//            for(int i = minPos; i < getItemCount(); i++){
//                insertView(i, visibleRect, recycler, false);
//            }
//        }else{
//            //右滑：向顶部滑动
//            int maxPos = getPosition(lastItem);
//            //填充可视区域左侧的View
//            for(int i = maxPos; i >= 0; i--){
//                insertView(i, visibleRect, recycler, true);
//            }
//        }
//        return travel;
//    }
//
//
//    //针对可视区域插入子视图
//    private void insertView(int pos , Rect visibleRect , RecyclerView.Recycler recycler , boolean firstPos){
//        Rect rect = mChildPositionRects.get(pos);
//        if(Rect.intersects(visibleRect , rect) && !mChildHasAttached.get(pos)){
//            //仅在可视区域其未显示的视图才执行插入视图
//            View item = recycler.getViewForPosition(pos);
//            if(firstPos){
//                addView(item , 0);
//            }else{
//                addView(item);
//            }
//            measureChildWithMargins(item,0,0);
//            layoutDecoratedWithMargins(item, rect.left - mScrollDistanceX, rect.top ,
//                    rect.right - mScrollDistanceX, rect.bottom);
//            mChildHasAttached.put(pos, true);
//        }
//    }



    //============================
    /**
     * 重写smoothScrollToPosition方法，实现平滑滑动及停留在中间位置
     * @param recyclerView
     * @param state
     * @param position 目标位置
     */
    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        RecyclerView.SmoothScroller smoothScroller = new RecyclerviewSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    /**
     * 重写LinearSmoothScroller自定义 中间对齐需要的校正位置
     */
    private static class RecyclerviewSmoothScroller extends LinearSmoothScroller{
        public RecyclerviewSmoothScroller(Context context) {
            super(context);
        }

        /**
         * 为了确保子视图在显示的位置中间位置，需要设置应当校正子视图的位置。<P/>
         * 子视图校正需要移动的距离为Recycler布局中间位置与子视图中间位置的距离<P/>
         * @param viewStart 子视图的左侧位置
         * @param viewEnd 子视图的右侧位置
         * @param boxStart RecyclerView视图的左侧位置
         * @param boxEnd RecyclerView视图的左侧位置
         * @return 返回子视图校正需要移动的距离
         */
        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }

        /**
         * 计算滑动的速度，返回1px滑动所需的时间，举例 如返回0.8f，即滑动1000个像素点距离需要0.8s<P/>
         * @param displayMetrics
         * @return 返回1px滑动所需的时间，单位ms
         */
        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return super.calculateSpeedPerPixel(displayMetrics);
        }
    }
}
